<?php


namespace phpboot\doctrine\Console;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\DBAL\Tools\Console as DBALConsole;
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
use PackageVersions\Versions;
use phpboot\doctrine\Command\EntityCommand;
use phpboot\doctrine\Command\MappingCommand;
use phpboot\doctrine\Command\UpdateCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Helper\HelperSet;

use Doctrine\ORM\Tools\Console\Command;

use OutOfBoundsException;

class ConsoleRunner
{

    public static function createHelperSet(EntityManagerInterface $entityManager): HelperSet
    {
        return new HelperSet(
            [
                'db' => new DBALConsole\Helper\ConnectionHelper($entityManager->getConnection()),
                'em' => new EntityManagerHelper($entityManager),
            ]
        );
    }

    /**
     * @param Application $cli
     *
     * * @return void
     */
    public static function addCommands(Application $cli): void
    {
        //parent::addCommands($cli);

        $cli->addCommands([
            new DBALConsole\Command\ImportCommand(),
            new DBALConsole\Command\ReservedWordsCommand(),
            new DBALConsole\Command\RunSqlCommand(),

            // ORM Commands
            new Command\ClearCache\CollectionRegionCommand(),
            new Command\ClearCache\EntityRegionCommand(),
            new Command\ClearCache\MetadataCommand(),
            new Command\ClearCache\QueryCommand(),
            new Command\ClearCache\QueryRegionCommand(),
            new Command\ClearCache\ResultCommand(),
            new Command\SchemaTool\CreateCommand(),
            new Command\SchemaTool\UpdateCommand(),
            new Command\SchemaTool\DropCommand(),
            new Command\EnsureProductionSettingsCommand(),
            new Command\ConvertDoctrine1SchemaCommand(),
            new Command\GenerateRepositoriesCommand(),
            new Command\GenerateEntitiesCommand(),
            new Command\GenerateProxiesCommand(),
            new Command\ConvertMappingCommand(),
            new Command\RunDqlCommand(),
            new Command\ValidateSchemaCommand(),
            new Command\InfoCommand(),
            new Command\MappingDescribeCommand(),
            new UpdateCommand(),
            new MappingCommand()
        ]);
    }

    /**
     * @param HelperSet $helperSet
     * @param array $commands
     * @return Application
     */
    public static function createApplication(HelperSet $helperSet, array $commands = []): Application
    {
        $cli = new Application('Doctrine Command Line Interface', Versions::getVersion('doctrine/orm'));
        $cli->setCatchExceptions(true);
        $cli->setHelperSet($helperSet);
        self::addCommands($cli);
        $cli->addCommands($commands);
        return $cli;
    }

    /**
     * @param HelperSet $helperSet
     * @param array $commands
     * @throws \Exception
     */
    public static function run(HelperSet $helperSet, array $commands = []): void
    {
        $cli = self::createApplication($helperSet, $commands);
        $cli->run();
    }

}
